﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Silverlight.Navigation.Mapping
{
    /// <summary>
    /// Represents the structure of an application.
    /// </summary>
    public abstract class ApplicationMap
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the ApplicationMap class.
        /// </summary>
        public ApplicationMap()
        {
            MainMenuItems = new MainMenuItemCollection();
        }

        #endregion

        #region Properties

        /// <summary>
        /// The current sub menu in the application.
        /// </summary>
        public SubMenuItem CurrentSubMenu { get; protected set; }

        /// <summary>
        /// The home menu item for the application.
        /// </summary>
        public abstract HomeMenuItem HomeMenuItem { get; protected set; }

        /// <summary>
        /// Main menu items of the application.
        /// </summary>
        public abstract MainMenuItemCollection MainMenuItems { get; protected set; }

        /// <summary>
        /// The path to the current node in the application.
        /// </summary>
        public MenuItemCollection Path { get; protected set; }

        /// <summary>
        /// Uri of the image used to separate items in the path to the current location in the application.
        /// </summary>
        public abstract string PathSeparatorImageUri { get; protected set; }

        /// <summary>
        /// Text used to separate items in the path to the current location in the application.
        /// </summary>
        public abstract string PathSeparatorText { get; protected set; }

        #endregion

        #region Methods

        /// <summary>
        /// Navigate to the specified sub menu item.
        /// </summary>
        /// <param name="node">The sub menu item to navigate to.</param>
        public void NavigateTo(SubMenuItem subMenuItem)
        {
            if (subMenuItem == null)
                throw new ArgumentNullException("subMenuItem");

            this.CurrentSubMenu = subMenuItem;

            BuildPath(subMenuItem);
        }

        /// <summary>
        /// Build the path to the current sub menu item.
        /// </summary>
        /// <param name="node">The sub menu to build the path to.</param>
        /// <remarks>
        /// Builds the path to the current sub menu by traversing the sub menu's tree.
        /// </remarks>
        private void BuildPath(SubMenuItem subMenuItem)
        {
            if (subMenuItem == null)
                throw new ArgumentNullException("subMenuitem");

            this.Path = new MenuItemCollection();

            this.Path.Insert(0, subMenuItem);

            if (subMenuItem.Parent != null)
                this.Path.Insert(0, subMenuItem.Parent);

            if (this.HomeMenuItem != null)
                this.Path.Insert(0, this.HomeMenuItem);
        }

        /// <summary>
        /// Finds a menu item by uri.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public MenuItem FindMenuItemByUri(string uri)
        {
            if (this.HomeMenuItem.ContentUri == uri)
                return this.HomeMenuItem;

            foreach (MainMenuItem mainMenuItem in this.MainMenuItems)
            {
                foreach (SubMenuItem subMenuItem in mainMenuItem.SubMenus)
                {
                    if (subMenuItem.ContentUri == uri)
                        return subMenuItem;
                }
            }

            return null;
        }

        #endregion
    }
}
